package com.asiainfo.framework.web.resolver;

import com.asiainfo.common.utils.support.Convert;
import com.asiainfo.framework.web.page.Pagination;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.List;

public class PaginationMethodArgumentResolver implements HandlerMethodArgumentResolver {

    public static final long DEFAULT_PAGE_NUM = 1L;
    public static final long DEFAULT_PAGE_SIZE = 10L;

    public static final String PAGE_NUM = "pageNum";
    public static final String PAGE_SIZE = "pageSize";
    public static final String ORDER_COLUMN_SPLIT_SYMBOL = ",";
    public static final String ORDER_BY_COLUMN_NAME = "orderByColumn";
    public static final String IS_ASC = "isAsc";

    private String pageNumName = PAGE_NUM;
    private String pageSizeName = PAGE_SIZE;

    public PaginationMethodArgumentResolver() {
    }

    public PaginationMethodArgumentResolver(String pageNumName, String pageSizeName) {
        this.pageNumName = pageNumName;
        this.pageSizeName = pageSizeName;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Pagination.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String pageNumStr = webRequest.getParameter(pageNumName);
        String pageSizeStr = webRequest.getParameter(pageSizeName);
        long pageNum = StringUtils.isEmpty(pageNumStr) ? DEFAULT_PAGE_NUM : Convert.toLong(pageNumStr).longValue();
        long pageSize = StringUtils.isEmpty(pageNumStr) ? DEFAULT_PAGE_SIZE : Convert.toLong(pageSizeStr).longValue();
        List<OrderItem> orders = getOrderByArgurments(webRequest);
        Pagination pagination = new Pagination(pageNum, pageSize);
        pagination.setOrders(orders);
        return pagination;
    }

    private List<OrderItem> getOrderByArgurments(NativeWebRequest webRequest) {
        String orderByColumn = webRequest.getParameter(ORDER_BY_COLUMN_NAME);
        if (StringUtils.isEmpty(orderByColumn)) {
            return null;
        }
        String[] columns = orderByColumn.split(ORDER_COLUMN_SPLIT_SYMBOL);
        String isAscStr = webRequest.getParameter(IS_ASC);
        if (!StringUtils.isEmpty(isAscStr)) {
            if (isAscStr.matches("0|false")) {
                return OrderItem.descs(columns);
            }
        }
        return OrderItem.ascs(columns);
    }
}
